package com.minhang.adsb.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.minhang.adsb.entity.ServerConfig;
import com.minhang.adsb.mapper.ServerConfigMapper;
import com.minhang.adsb.service.PushStrategy;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@Slf4j
public class V1HttpPushStrategy implements PushStrategy {
    private final ServerConfigMapper serverConfigMapper;
    @Autowired
    public V1HttpPushStrategy(ServerConfigMapper serverConfigMapper) {
        this.serverConfigMapper = serverConfigMapper;
    }
    private final ConcurrentHashMap<Long, AtomicInteger> timeoutCounters = new ConcurrentHashMap<>();
    // 优化后的HTTP客户端配置
    private static final OkHttpClient asyncClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)  // 新增写超时
            .connectionPool(new ConnectionPool(200, 5, TimeUnit.MINUTES))
            .build();

    @Override
    public void push(ServerConfig server, String jsonPayload) {
        MediaType jsonType = MediaType.get("application/json; charset=utf-8");
        processServer(server, jsonPayload, jsonType);
    }

    private void processServer(ServerConfig server, String jsonPayload, MediaType jsonType) {
        Request request = buildRequest(server, jsonPayload, jsonType);
        executeRequestWithRetry(server, request);
    }

    private Request buildRequest(ServerConfig server, String payload, MediaType mediaType) {
        return new Request.Builder()
                .url(server.getEndpoint())
                .post(RequestBody.create(payload, mediaType))
                .build();
    }

    private void executeRequestWithRetry(ServerConfig server, Request request) {
        try (Response response = asyncClient.newCall(request).execute()) {
            handleResponse(response, server);
        } catch (IOException e) {
            handleIOException(server, e);
        }
    }

    private void handleIOException(ServerConfig server, IOException e) {
        handleTimeout(server);
        log.error("服务器 [{}] 网络错误: {}", server.getEndpoint(), e.getMessage());
    }

    // 核心超时处理逻辑
    private synchronized void handleTimeout(ServerConfig server) {
        long serverId = server.getId();
        AtomicInteger counter = timeoutCounters.computeIfAbsent(
                serverId,
                k -> new AtomicInteger(0)
        );

        int currentCount = counter.incrementAndGet();
        log.warn("服务器 [ID:{}] 第 {} 次超时", serverId, currentCount);

        if (currentCount >= 50) {
            disableServer(serverId);
            timeoutCounters.remove(serverId);  // 重置计数器
        }
    }

    private void disableServer(long serverId) {
        ServerConfig serverConfig = new ServerConfig();
        serverConfig.setId(serverId);
        serverConfig.setIsActive(0);
        int result = serverConfigMapper.updateById(serverConfig);

        if (result > 0) {
            log.info("已禁用连续超时50次的服务器 [ID:{}]", serverId);
        } else {
            log.error("禁用服务器失败 [ID:{}]", serverId);
        }
    }

    private void handleResponse(Response response, ServerConfig server) throws IOException {
        if (!response.isSuccessful()) {
            log.error("服务器 [{}] 返回异常状态码: {}", server.getDescription(), response.code());
            return;
        }

        // 请求成功时重置计数器
        log.info("服务器 [{}] 响应成功", server.getDescription());
        timeoutCounters.remove(server.getId());
        //todo 处理响应体
//        try (ResponseBody body = response.body()) {
//            if (body != null) {
//                processResponseBody(server, body);
//            }
//        }
    }

    private void processResponseBody(ServerConfig server, ResponseBody body) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(body.byteStream());

        if (rootNode.has("code")) {
            int code = rootNode.get("code").asInt();
            log.info("服务器 [{}] 业务响应码: {}", server.getEndpoint(), code);
        }
    }
}
